home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-03
/
qbasicpg.zip
/
BOWLING.BAS
< prev
next >
Wrap
BASIC Source File
|
1989-08-31
|
14KB
|
352 lines
' BOWLING.BAS
' This program uses random numbers to simulate a 10-frame bowling game.
' declare subprograms and function
DECLARE SUB ScoreCard ()
DECLARE SUB Pause ()
DECLARE FUNCTION GetRandBowl% (values%)
DECLARE SUB ShowBowl (value%)
DECLARE SUB DrawPins (pins%)
DECLARE SUB ProcessSpare (extraBall%, offset%)
DECLARE SUB TenthFrameStrike ()
DECLARE SUB TenthFrameSpare ()
' declare global variables and constants
COMMON SHARED total%, strike%, spare%, score$
CONST FRAMEROW% = 3: CONST SCOREROW% = 5
CONST FALSE% = 0, TRUE% = NOT FALSE%
RANDOMIZE TIMER ' seed random number generator with system clock
score$ = "###" ' template for displaying total% with PRINT USING
CLS
ScoreCard ' call ScoreCard to display frames and gutters
DrawPins 10 ' set a fresh rack of 10 pins to start game
FOR i% = 1 TO 10 ' for each of the 10 frames...
Pause ' pause the action
DrawPins 10 ' set a fresh rack of 10 pins
firstBowl% = GetRandBowl%(10) ' get random number for first ball
strikeDelay% = TRUE% ' set "strike" flag to true
IF (firstBowl% = 10) THEN ' if first ball is a strike...
ShowBowl 10 ' show a throw that gets 10 pins
DrawPins 0 ' show an empty lane
LOCATE FRAMEROW%, 3 + ((i% - 1) * 6) ' use i% to locate frame
PRINT "X" ' ...and print "X" for strike
pinsDown% = 10 ' set pinsDown% count to 10
strike% = strike% + 1 ' increment the number of strikes
noStrikes% = FALSE% ' set "no strike" flag to false
' if 3 strikes have been bowled, set flag to process the first
IF (strike% = 3) THEN strikeDelay% = TRUE% ELSE strikeDelay% = FALSE%
' if working on a spare, calculate score for last frame
IF (spare%) THEN ProcessSpare firstBowl%, i%
ELSE ' if first throw was not a strike...
ShowBowl firstBowl% ' show an appropriate throw
DrawPins 10 - firstBowl% ' draw the remaining pins
LOCATE FRAMEROW%, 2 + ((i% - 1) * 6) ' use i% to locate frame
PRINT firstBowl% ' ...and display first ball
' if working on a spare, calculate score for last frame
IF (spare%) THEN ProcessSpare firstBowl%, i%
Pause ' pause the action
' get random number for second ball
secondBowl% = GetRandBowl%(10 - firstBowl%)
ShowBowl firstBowl% + secondBowl% ' show the ball
DrawPins 10 - (firstBowl% + secondBowl%) ' draw remainder
pinsDown% = firstBowl% + secondBowl% ' add up pins
noStrikes% = TRUE% ' set "no strike" flag to true
IF (pinsDown% = 10) THEN ' if two balls make a spare...
LOCATE FRAMEROW%, 5 + ((i% - 1) * 6) ' locate frame
PRINT "/" ' ...and print "/" for spare
spare% = TRUE% ' set "spare" flag to true
ELSE ' if not a spare...
LOCATE FRAMEROW%, 4 + ((i% - 1) * 6) ' locate frame
PRINT secondBowl% ' ...and display second ball
END IF
END IF
' process outstanding strikes if bonus balls are available
IF (strike% >= 1) AND (strikeDelay%) THEN
IF (strike% = 1) THEN ' if single strike
total% = total% + 10 + firstBowl% + secondBowl%
LOCATE SCOREROW%, 3 + ((i% - 2) * 6) ' locate last frame
PRINT USING score$; total% ' print total score
strikeDelay% = FALSE% ' set "strike" flag to false
END IF
IF (strike% = 2) OR (strike% = 3) THEN ' if double or triple
total% = total% + 10 + 10 + firstBowl% ' total pins
LOCATE SCOREROW%, 3 + ((i% - 3) * 6) ' move 2 frames back
PRINT USING score$; total% ' print total score
IF (noStrikes%) THEN ' if all bonus balls available
total% = total% + 10 + firstBowl% + secondBowl%
LOCATE SCOREROW%, 3 + ((i% - 2) * 6) ' get last frame
PRINT USING score$; total% ' print total score
strike% = 0 ' set number of
END IF ' strikes to zero
END IF
strike% = strike% - 1 ' decrement number of strikes
IF (strike% < 0) THEN strike% = FALSE% ' don't go below zero
END IF
IF (pinsDown% < 10) AND (NOT strike%) THEN ' calculate pin total
total% = total% + pinsDown% ' for open frame
LOCATE SCOREROW%, 3 + ((i% - 1) * 6) ' and display score
PRINT USING score$; total%
END IF
NEXT i%
IF (strike%) THEN TenthFrameStrike ' if a strike in the 10th frame
IF (spare%) THEN TenthFrameSpare ' if a spare in the 10th frame
END ' end main program
SUB DrawPins (num%)
' DrawPins displays the number of pins specified by num%.
' CHR$(173) is an upside-down exclamation mark from the
' IBM extended character set used to represent a pin.
COLOR 14 ' set color to yellow
LOCATE 21, 70 ' this is the last pin to be knocked down
IF (num% = 10) THEN PRINT CHR$(173) ELSE PRINT " "
LOCATE 20, 68
IF (num% >= 9) THEN PRINT CHR$(173) ELSE PRINT " "
LOCATE 19, 66
IF (num% >= 8) THEN PRINT CHR$(173) ELSE PRINT " "
LOCATE 19, 70
IF (num% >= 7) THEN PRINT CHR$(173) ELSE PRINT " "
LOCATE 18, 68
IF (num% >= 6) THEN PRINT CHR$(173) ELSE PRINT " "
LOCATE 18, 64
IF (num% >= 5) THEN PRINT CHR$(173) ELSE PRINT " "
LOCATE 17, 66
IF (num% >= 4) THEN PRINT CHR$(173) ELSE PRINT " "
LOCATE 16, 68
IF (num% >= 3) THEN PRINT CHR$(173) ELSE PRINT " "
LOCATE 17, 70
IF (num% >= 2) THEN PRINT CHR$(173) ELSE PRINT " "
LOCATE 15, 70 ' this is the first pin to be knocked down
IF (num% >= 1) THEN PRINT CHR$(173) ELSE PRINT " "
COLOR 7 ' set color back to white
END SUB
FUNCTION GetRandBowl% (values%)
' GetRandBowl% returns a random number between 1 and values% to
' the calling procedure.
GetRandBowl% = INT(RND * (values% + 1))
END FUNCTION
SUB Pause
' Pause returns the ball to the top of the lane and pauses the action.
FOR ballPos% = 68 TO 3 STEP -1 ' return ball to top of lane
SOUND 150, .1 ' play appropriate sound
LOCATE 12, ballPos%: PRINT CHR$(2) ' ball is ASCII code number 2
SOUND 160, .1
LOCATE 12, ballPos% + 1: PRINT " "
SOUND 1170, .1
NEXT ballPos%
LOCATE 8, 1
COLOR 14, 1 ' set color to yellow-on-blue
INPUT "Press Enter to bowl ", dummy$ ' pause the action
COLOR 7, 0 ' return color to defaults
LOCATE 12, 3: PRINT " " ' hide resting place of ball
END SUB
SUB ProcessSpare (extraBall%, offset%)
' ProcessSpare calculates the score for the preceeding frame when
' the extra ball is available. Offset% is the frame location.
total% = total% + 10 + extraBall% ' calculate frame score
LOCATE SCOREROW%, 3 + ((offset% - 2) * 6) ' use offset% to get frame
PRINT USING score$; total% ' display the total
spare% = FALSE% ' set "spare" switch to false
END SUB
SUB ScoreCard
' ScoreCard displays the bowling scorecard and the alley gutters.
COLOR 3 ' set foreground color to cyan
PRINT " 1 2 3 4 5 6 7 8 9 10"
PRINT STRING$(63, "-")
PRINT "| | | | | | | | | | |"
PRINT "| | | | | | | | | | |"
PRINT "| | | | | | | | | | |"
PRINT STRING$(63, "-")
LOCATE 13, 5
PRINT STRING$(66, "-")
LOCATE 23, 5
PRINT STRING$(66, "-")
COLOR 7 ' set foreground color to white
END SUB
SUB ShowBowl (pins%)
' ShowBowl shows the ball rolling down the lane through the pins
' with appropriate sounds. The pins% parameter represents the
' number of pins that should fall and is used to send the ball
' in the right direction.
LOCATE 8, 1 ' cover up the "Press Enter" message
PRINT SPACE$(20)
value% = (pins% + 1) \ 2 ' set target range
IF (value% < 3) AND (value% >= 0) THEN value% = value% + 1
row% = 18 ' set starting row
FOR i% = 2 TO 68 STEP 10 ' roll ball down lane
FOR j% = 1 TO 10
SOUND 63, .2 ' play appropriate sound
LOCATE row%, i% - 1 + j%: PRINT " " ' cover up tracks
IF (i% > 54) AND (row% <= 18) THEN ' change sound when in
FOR k% = 1 TO 5 ' the pins
note% = INT(RND(1) * 150): SOUND 50 + note%, .1
NEXT k%
END IF
IF (i% > 61) AND (row% >= 19) AND (row <= 21) THEN
FOR k% = 1 TO 5
note% = INT(RND(1) * 150): SOUND 50 + note%, .1
NEXT k%
END IF
SOUND 68, .2
LOCATE row%, i% + j%: PRINT CHR$(2) ' display ball
SOUND 65, .2
NEXT j%
LOCATE row%, i% - 1 + j%: PRINT " " ' cover up tracks
IF (value% >= 5) THEN row% = row% - 1
row% = row% + 1: value% = value% + 1 ' move to next row
NEXT i%
END SUB
SUB TenthFrameSpare
' TenthFrameSpare handles the throwing of another ball and the
' calculation of the 10th frame if there is a spare in the 10th.
Pause ' pause for extra ball
DrawPins 10 ' set up a fresh rack of 10 pins
firstBowl% = GetRandBowl%(10) ' get a random number for extra ball
ShowBowl firstBowl% ' show the ball rolling down the alley
DrawPins 10 - firstBowl% ' take away the pins that fell
IF (firstBowl% = 10) THEN ' if the extra ball is a 10 then
LOCATE FRAMEROW%, 61 ' locate the extra slot
PRINT "X" ' and display an "X" for strike
ELSE
LOCATE FRAMEROW%, 60 ' if the extra ball is not 10 then
PRINT firstBowl% ' print its value in extra slot
END IF
ProcessSpare firstBowl%, 11 ' calculate the final value of the
' 10th frame
END SUB
SUB TenthFrameStrike
' TenthFrameStrike handles the throwing of two extra balls and any
' unresolved frames if a strike is bowled in the 10th frame.
Pause ' pause for first ball
DrawPins 10 ' set up a fresh rack of 10 pins
firstBowl% = GetRandBowl%(10) ' get random number for first ball
ShowBowl firstBowl% ' show the ball rolling down the alley
DrawPins 10 - firstBowl% ' take away the pins that fell
IF (firstBowl% = 10) THEN ' if the first ball is a 10 then
LOCATE FRAMEROW%, 59 ' locate the second slot
PRINT "X" ' and display an "X" for strike
IF (strike% = 2) THEN ' if working on a double,
total% = total% + 10 + 10 + firstBowl% ' get last frame total
LOCATE SCOREROW%, 3 + (8 * 6) ' locate last frame
PRINT USING score$; total% ' record frame score
END IF
Pause ' pause for second ball
DrawPins 10 ' set up a fresh rack of 10 pins
secondBowl% = GetRandBowl%(10) ' get a random number for ball
ShowBowl secondBowl% ' show the ball rolling down the alley
DrawPins 10 - secondBowl% ' take away the pins that fell
IF (secondBowl% = 10) THEN ' if this ball is also a 10,
LOCATE FRAMEROW%, 61 ' locate the extra slot
PRINT "X" ' and display an "X" for strike
ELSE
LOCATE FRAMEROW%, 60 ' if the ball is not 10 then
PRINT secondBowl% ' print its value in extra slot
END IF
ELSE ' if the first ball is not a 10,
IF (strike% = 2) THEN ' process the remaining double (if any)
total% = total% + 10 + 10 + firstBowl% ' get last frame total
LOCATE SCOREROW%, 3 + (8 * 6) ' locate last frame
PRINT USING score$; total% ' display frame score
END IF
secondBowl% = GetRandBowl%(10 - firstBowl%) ' get second ball
ShowBowl secondBowl% + firstBowl% ' show ball
DrawPins 10 - (secondBowl% + firstBowl%) ' draw remaining pins
LOCATE FRAMEROW%, 58
PRINT firstBowl% ' display first ball
IF (secondBowl% + firstBowl% = 10) THEN ' if 10 down then
LOCATE FRAMEROW%, 61 ' print a "/" for
PRINT "/" ' spare
ELSE
LOCATE FRAMEROW%, 60 ' if less than 10,
PRINT secondBowl% ' print the number
END IF
END IF
total% = total% + 10 + firstBowl% + secondBowl% ' calculate and
LOCATE SCOREROW%, 57 ' display final frame
PRINT USING score$; total%
END SUB